
/**
 * Copyright 2009 cestum.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.waveprotocol.wave.model.document.operation.algorithm {
import mx.collections.IViewCursor;

import org.goverla.collections.ArrayList;
import org.waveprotocol.wave.model.document.operation.BufferedDocOp;
import org.waveprotocol.wave.model.operation.OperationException;



/**
 * A class that collects document operations together and composes them in an
 * efficient manner.
 */
public final class DocOpCollector {

  private var operations:ArrayList= new ArrayList();

  public function add(operation:BufferedDocOp):void {
	  
    var iterator:IViewCursor = operations.createCursor();
    while (!iterator.afterLast) {
      var nextOperation:BufferedDocOp= BufferedDocOp(iterator.current);
      if (nextOperation == null) {
        iterator.insert(operation);
        return;
      }
      iterator.insert(null);
      operation = compose(nextOperation, operation);
    }
    operations.addItem(operation);
  }

  public function composeAll():BufferedDocOp {
    var result:BufferedDocOp= null;
    for (var i:int=0; i<operations.length; i++) {
    	var operation:BufferedDocOp= BufferedDocOp(operations.getItemAt(i));
      if (operation != null) {
        result = (result != null) ? compose(operation, result) : operation;
      }
    }
    operations.removeAll();
    return result;
  }

  private function compose(op1:BufferedDocOp, op2:BufferedDocOp):BufferedDocOp {
    try {
      return Composer.compose(op1, op2);
    } catch (e:OperationException) {
      throw new Error("");
    }
	return null;
  }

}
}